package com.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dto.OrderAddDto;
import com.dto.OrderDto;
import com.dto.OrderSaveDto;
import com.dto.PurchaseDto;
import com.mapper.*;
import com.po.*;
import com.service.OrderService;
import com.service.PurchaseService;
import com.vo.PurchaseDetailVo;
import com.vo.PurchaseVo;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

@RequiredArgsConstructor
@Slf4j
@Service
public class PurchaseServiceImpl extends ServiceImpl<PurchaseMapper, Purchase> implements PurchaseService {

    private final ItemMinuteMapper itemMinuteMapper;

    private final ItemMapper itemMapper;

    private final PurchaseDetailMapper purchaseDetailMapper;

    private final OrderService orderService;

    private final OrderDetailMapper orderDetailMapper;


    @Override
    @Transactional
    public void isave(String strId) {
        List<String> list= Arrays.asList(strId.split(","));
        List<Long> ids = list.stream().map(Long::parseLong).collect(Collectors.toList());
        ItemMinute itemMinute = itemMinuteMapper.selectById(ids.get(0));
        Long itemId = itemMinute.getItemId();
        LambdaQueryWrapper<ItemMinute> eq = new LambdaQueryWrapper<ItemMinute>()
                .eq(ItemMinute::getItemId, itemId);
        Integer count = itemMinuteMapper.selectCount(eq);
        Purchase purchase = new Purchase();
        LocalDateTime now = LocalDateTime.now();
        purchase.setNum(count);
        purchase.setCreateId(StpUtil.getLoginIdAsLong());
        purchase.setCreateTime(now);
        purchase.setItemId(itemId);
        purchase.setOverTime(now.plusDays(1));
        save(purchase);
        OrderSaveDto orderSaveDto = new OrderSaveDto();
        List<OrderDto> orderDtolist = new ArrayList<>();
        Item item = itemMapper.selectById(itemId);
        OrderDto orderDto = new OrderDto();
        BeanUtil.copyProperties(item,orderDto);
        orderDto.setNum(1);
        orderDto.setItemPrice(item.getPrice());
        orderDto.setItemId(itemId);
        List<OrderAddDto> orderAddDtoList = new ArrayList<>();
        ids.forEach(id -> {
            PurchaseDetail purchaseDetail = new PurchaseDetail();
            purchaseDetail.setPurchaseId(purchase.getId());
            purchaseDetail.setItemMinuteId(id);
            purchaseDetail.setUserId(StpUtil.getLoginIdAsLong());
            purchaseDetail.setCreateTime(LocalDateTime.now());
            purchaseDetailMapper.insert(purchaseDetail);
            OrderAddDto orderAddDto = new OrderAddDto();
            ItemMinute minute = itemMinuteMapper.selectById(id);
            orderAddDto.setId(id);
            orderAddDto.setPrice(minute.getPrice());
            orderAddDtoList.add(orderAddDto);
        });
        orderDto.setOrderAddDtoList(orderAddDtoList);
        orderDto.setPurchaseId(purchase.getId());
        orderDtolist.add(orderDto);
        orderSaveDto.setOrderDtolist(orderDtolist);
        orderService.add(orderSaveDto);
    }

    @Override
    @Transactional
    public List<PurchaseVo> ilist(Long id) {
        LambdaQueryWrapper<Purchase> eq = new LambdaQueryWrapper<Purchase>()
                .eq(Purchase::getItemId, id)
                .eq(Purchase::getStatus,0);
        List<Purchase> purchaseList = list(eq);
        List<PurchaseVo> purchaseVoList = new ArrayList<>();
        purchaseList.forEach(purchase -> {
            PurchaseVo purchaseVo = new PurchaseVo();
            BeanUtil.copyProperties(purchase,purchaseVo);
            LambdaQueryWrapper<PurchaseDetail> wrapper = new LambdaQueryWrapper<PurchaseDetail>()
                    .eq(PurchaseDetail::getPurchaseId, purchase.getId());
            List<PurchaseDetail> purchaseDetails = purchaseDetailMapper.selectList(wrapper);
            List<PurchaseDetailVo> purchaseDetailVoList = new ArrayList<>();
            purchaseDetails.forEach(Detail -> {
                PurchaseDetailVo purchaseDetailVo = new PurchaseDetailVo();
                BeanUtil.copyProperties(Detail,purchaseDetailVo);
                purchaseDetailVoList.add(purchaseDetailVo);
            });
            purchaseVo.setPurchaseDetailVoList(purchaseDetailVoList);
            purchaseVoList.add(purchaseVo);
        });
        return purchaseVoList;
    }

    @Override
    public void add(PurchaseDto purchaseDto) {
        String itemMinuteId = purchaseDto.getItemMinuteId();
        List<String> list= Arrays.asList(itemMinuteId.split(","));
        List<Long> ids = list.stream().map(Long::parseLong).collect(Collectors.toList());
        ItemMinute itemMinute = itemMinuteMapper.selectById(ids.get(0));
        OrderSaveDto orderSaveDto = new OrderSaveDto();
        List<OrderDto> orderDtolist = new ArrayList<>();
        Item item = itemMapper.selectById(itemMinute.getItemId());
        OrderDto orderDto = new OrderDto();
        BeanUtil.copyProperties(item,orderDto);
        orderDto.setNum(1);
        orderDto.setItemPrice(item.getPrice());
        orderDto.setItemId(itemMinute.getItemId());
        List<OrderAddDto> orderAddDtoList = new ArrayList<>();
        ids.forEach(id -> {
            PurchaseDetail purchaseDetail = new PurchaseDetail();
            purchaseDetail.setPurchaseId(purchaseDto.getPurchaseId());
            purchaseDetail.setItemMinuteId(id);
            purchaseDetail.setUserId(StpUtil.getLoginIdAsLong());
            purchaseDetail.setCreateTime(LocalDateTime.now());
            purchaseDetailMapper.insert(purchaseDetail);
            OrderAddDto orderAddDto = new OrderAddDto();
            ItemMinute minute = itemMinuteMapper.selectById(id);
            orderAddDto.setId(id);
            orderAddDto.setPrice(minute.getPrice());
            orderAddDtoList.add(orderAddDto);
        });
        orderDto.setOrderAddDtoList(orderAddDtoList);
        orderDto.setPurchaseId(purchaseDto.getPurchaseId());
        orderDtolist.add(orderDto);
        orderSaveDto.setOrderDtolist(orderDtolist);
        orderService.add(orderSaveDto);
    }

    @Override
    public PurchaseVo get(Long id) {
        Purchase purchase = getById(id);
        PurchaseVo purchaseVo = new PurchaseVo();
        BeanUtil.copyProperties(purchase,purchaseVo);
        LambdaQueryWrapper<PurchaseDetail> wrapper = new LambdaQueryWrapper<PurchaseDetail>()
                .eq(PurchaseDetail::getPurchaseId, id);
        List<PurchaseDetail> purchaseDetails = purchaseDetailMapper.selectList(wrapper);
        List<PurchaseDetailVo> purchaseDetailVoList = new ArrayList<>();
        purchaseDetails.forEach(purchaseDetail -> {
            PurchaseDetailVo purchaseDetailVo = new PurchaseDetailVo();
            BeanUtil.copyProperties(purchaseDetail,purchaseDetailVo);
            purchaseDetailVoList.add(purchaseDetailVo);
        });
        purchaseVo.setPurchaseDetailVoList(purchaseDetailVoList);
        return purchaseVo;
    }

    @Override
    public List<PurchaseVo> mylist() {
        LambdaQueryWrapper<PurchaseDetail> eq = new LambdaQueryWrapper<PurchaseDetail>()
                .eq(PurchaseDetail::getUserId, StpUtil.getLoginIdAsLong());
        List<PurchaseDetail> purchaseDetails = purchaseDetailMapper.selectList(eq);
        Set<Long> ids = new HashSet<>();
        purchaseDetails.forEach(purchaseDetail -> {
            ids.add(purchaseDetail.getPurchaseId());
        });
        List<PurchaseVo> purchaseVoList = new ArrayList<>();
        ids.forEach(id -> {
            PurchaseVo purchaseVo = new PurchaseVo();
            LambdaQueryWrapper<Purchase> queryWrapper = new LambdaQueryWrapper<Purchase>()
                    .eq(Purchase::getId, id);
            Purchase purchase = getOne(queryWrapper);
            BeanUtil.copyProperties(purchase,purchaseVo);
            LambdaQueryWrapper<PurchaseDetail> wrapper = new LambdaQueryWrapper<PurchaseDetail>()
                    .eq(PurchaseDetail::getPurchaseId, purchase.getId());
            List<PurchaseDetail> Details = purchaseDetailMapper.selectList(wrapper);
            List<PurchaseDetailVo> purchaseDetailVoList = new ArrayList<>();
            Details.forEach(Detail -> {
                PurchaseDetailVo purchaseDetailVo = new PurchaseDetailVo();
                BeanUtil.copyProperties(Detail,purchaseDetailVo);
                purchaseDetailVoList.add(purchaseDetailVo);
            });
            purchaseVo.setPurchaseDetailVoList(purchaseDetailVoList);
            purchaseVoList.add(purchaseVo);
        });
        return purchaseVoList;
    }

    @Override
    @Transactional
    public void delete(Long id) {
        LambdaUpdateWrapper<Purchase> wrapper = new LambdaUpdateWrapper<Purchase>()
                .set(Purchase::getStatus, 1)
                .in(Purchase::getId, id);
        update(null,wrapper);
        LambdaQueryWrapper<OrderDetail> eq = new LambdaQueryWrapper<OrderDetail>()
                .eq(OrderDetail::getPurchaseId, id);
        List<OrderDetail> orderDetails = orderDetailMapper.selectList(eq);
        orderDetails.forEach(orderDetail -> {
            LambdaUpdateWrapper<Orders> in = new LambdaUpdateWrapper<Orders>()
                    .set(Orders::getStatus, 5)
                    .set(Orders::getCloseTime, LocalDateTime.now())
                    .set(Orders::getUpdateTime, LocalDateTime.now())
                    .in(Orders::getId, orderDetail.getOrderId());
            orderService.update(null,in);
        });
    }


}
